import { useState, useEffect, useRef } from 'react';
import { Input, Button, List, Avatar, message as antdMessage, Popconfirm, Modal } from 'antd';
import { UserOutlined, SendOutlined, DeleteOutlined } from '@ant-design/icons';
import styles from './chat.module.css';
import { useNavigate } from 'react-router-dom';
import { saveMessage, updateUserData } from './messageStore';
import ImageUploader from './ImageUploader';

function generateUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    const r = (Math.random() * 16) | 0;
    const v = c === 'x' ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

const MESSAGES_KEY = 'chat_messages_v3';
const USER_DATA_KEY = 'chat_user_data_v3';

function MentionPopover({ users, onSelect, activeIndex, position }) {
  return (
    <div
      style={{
        position: 'fixed',
        left: position.x,
        top: position.y,
        width: 200,
        zIndex: 1050,
        background: '#fff',
        borderRadius: 8,
        boxShadow: '0 3px 6px -4px rgba(0,0,0,0.12), 0 6px 16px 0 rgba(0,0,0,0.08)'
      }}
    >
      <List
        size="small"
        dataSource={users}
        renderItem={(user, index) => (
          <List.Item
            onClick={() => onSelect(user)}
            style={{
              cursor: 'pointer',
              padding: '8px 12px',
              backgroundColor: index === activeIndex ? '#f5f5f5' : 'transparent'
            }}
          >
            <List.Item.Meta
              avatar={<Avatar size="small" icon={<UserOutlined />} />}
              title={user.username}
            />
          </List.Item>
        )}
      />
    </div>
  );
}

function UserSettingModal({ visible, initialName, onSave, onCancel }) {
  const [name, setName] = useState(initialName || '');
  const [loading, setLoading] = useState(false);

  const handleSubmit = () => {
    if (!name.trim()) {
      antdMessage.warning('请输入有效昵称');
      return;
    }
    setLoading(true);
    onSave(name);
    setLoading(false);
  };

  return (
    <Modal
      title="修改昵称"
      open={visible}
      onOk={handleSubmit}
      onCancel={onCancel}
      footer={[
        <Button key="cancel" onClick={onCancel}>
          取消
        </Button>,
        <Button
          key="submit"
          type="primary"
          loading={loading}
          onClick={handleSubmit}
        >
          保存
        </Button>,
      ]}
    >
      <Input
        prefix={<UserOutlined />}
        placeholder="输入新昵称"
        value={name}
        onChange={(e) => setName(e.target.value)}
        onPressEnter={handleSubmit}
        maxLength={20}
      />
    </Modal>
  );
}

// 表情选择器组件
function EmojiPicker({ onSelect, position }) {
  // 表情列表
  const emojis = ['😊', '😂', '😍', '🤮', '🥰', '🤢', '🤑', '🫥','😶‍🌫️','😪','😴', '😎', '😒', '😭', '🌹', '🤣', '😘', '😎', '🤔', '😮', '😢', '😡', '👍', '👋', '❤️', '🎉', '🔥'];

  return (
    <div
      style={{
        // position: 'fixed',
        left: position.x,
        top: position.y,
        width: 420,
        background: '#fff',
        borderRadius: 8,
        boxShadow: '0 3px 6px -4px rgba(0,0,0,0.12), 0 6px 16px 0 rgba(0,0,0,0.08)',
        padding: '8px 8px 8px 0px',
        display: 'flex',
        flexWrap: 'wrap',
        justifyContent: 'space-between',
        zIndex: 1050
      }}
    >
      {emojis.map((emoji, index) => (
        <span
          key={index}
          onClick={() => onSelect(emoji)}
          style={{
            cursor: 'pointer',
            fontSize: '24px',
            margin: '5px',
            transition: 'transform 0.2s',
            ':hover': {
              transform: 'scale(1.2)'
            }
          }}
        >
          {emoji}
        </span>
      ))}
    </div>
  );
}

function Chat() {
  const [inputMsg, setInputMsg] = useState('');
  const [messages, setMessages] = useState(() => {
    const saved = localStorage.getItem(MESSAGES_KEY);
    return saved ? JSON.parse(saved) : [];
  });
  const [settingVisible, setSettingVisible] = useState(false);
  const [showMention, setShowMention] = useState(false);
  const [mentionUsers, setMentionUsers] = useState([]);
  const [mentionPosition, setMentionPosition] = useState({ x: 0, y: 0 });
  const [activeMentionIndex, setActiveMentionIndex] = useState(0);
  const [otherUserName, setOtherUserName] = useState('好友聊天');
  const [showEmojiPicker, setShowEmojiPicker] = useState(false);
  const [emojiPosition, setEmojiPosition] = useState({ x: 0, y: 0 });
  const [showImageUploader, setShowImageUploader] = useState(false);
  const [selectedImage, setSelectedImage] = useState('');

  const [userData, setUserData] = useState(() => {
    const saved = localStorage.getItem(USER_DATA_KEY);
    return saved ? JSON.parse(saved) : {
      username: `user_${Math.random().toString(36).substring(2, 5)}`,
      deviceId: typeof crypto.randomUUID === 'function'
        ? crypto.randomUUID()
        : generateUUID()
    };
  });

  const wsRef = useRef(null);
  const listRef = useRef(null);
  const inputRef = useRef(null);

  useEffect(() => {
    localStorage.setItem(MESSAGES_KEY, JSON.stringify(messages));
  }, [messages]);

  useEffect(() => {
    localStorage.setItem(USER_DATA_KEY, JSON.stringify(userData));
  }, [userData]);

  // 从消息中获取对方的用户名
  useEffect(() => {

    if (messages.length > 0) {
      // 找到不是自己发送的最新消息
      const otherMessages = messages.filter(msg => !msg.isMe);
      if (otherMessages.length > 0) {
        const latestOtherMessage = otherMessages[otherMessages.length - 1];
        setOtherUserName(latestOtherMessage.user);
      }
    }
  }, [messages]);

  useEffect(() => {
    // 切换设备需要根据ip改网络地址
    // const wsUrl = 'ws://192.168.132.138:3002';
    const wsUrl = 'ws://192.168.231.119:3002'; 
    wsRef.current = new WebSocket(wsUrl);

    wsRef.current.onopen = () => {
      // antdMessage.success('已连接到聊天服务器');
      if (messages.length > 0) {
        wsRef.current.send(JSON.stringify({
          type: 'history_sync',
          messages: messages,
          deviceId: userData.deviceId
        }));
      }
    };

    wsRef.current.onmessage = async (e) => {
      let msg;
      try {
        msg = e.data instanceof Blob
          ? JSON.parse(await e.data.text())
          : JSON.parse(e.data);
      } catch (err) {
        console.error('消息解析失败:', err);
        return;
      }

      if (msg.type === 'history_response') {
        setMessages(msg.messages.map(m => ({
          ...m,
          isMe: m.deviceId === userData.deviceId
        })));
        return;
      }

      if (msg.type === 'user_updated') {
        setMessages(prev =>
          prev.map(m =>
            m.deviceId === msg.deviceId
              ? { ...m, user: msg.newName }
              : m
          )
        );
        return;
      }

      const newMessage = {
        ...msg,
        isMe: msg.deviceId === userData.deviceId,
        mentions: extractMentions(msg.text)
      };

      setMessages(prev => [...prev, newMessage]);

      // 如果是对方发送的消息，更新对方的用户名
      if (!newMessage.isMe) {
        setOtherUserName(newMessage.user);
      }

      setTimeout(() => {
        listRef.current?.scrollTo(0, listRef.current.scrollHeight);
      }, 100);
    };

    wsRef.current.onerror = () => {
      // antdMessage.error('连接服务器失败！');
    };
    return () => wsRef.current?.close();
  }, [userData.deviceId]);

  function extractMentions(text) {
    const mentions = [];
    const regex = /@([^\s@]+)/g;
    let match;
    while ((match = regex.exec(text)) !== null) {
      mentions.push(match[1]);
    }
    return mentions;
  }

  const renderMessageText = (text) => {
    // 检查是否是图片消息（以data:image/开头的base64编码）
    if (text.startsWith('data:image/')) {
      return <img src={text} alt="图片消息" style={{ maxWidth: '100%', maxHeight: '200px', borderRadius: '8px' }} />;
    }
    
    const parts = [];
    let lastIndex = 0;
    const regex = /@([^\s@]+)/g;
    let match;

    while ((match = regex.exec(text)) !== null) {
      if (match.index > lastIndex) {
        parts.push(text.slice(lastIndex, match.index));
      }

      parts.push(
        <span
          key={match.index}
          style={{
            color: '#1890ff',
            backgroundColor: '#e6f7ff',
            padding: '0 4px',
            borderRadius: 3
          }}
        >
          @{match[1]}
        </span>
      );

      lastIndex = regex.lastIndex;
    }

    if (lastIndex < text.length) {
      parts.push(text.slice(lastIndex));
    }

    return parts.map((part, i) => <span key={i}>{part}</span>);
  };

  const handleInputChange = (e) => {
    const value = e.target.value;
    setInputMsg(value);

    const lastAtPos = value.lastIndexOf('@');
    if (lastAtPos > -1 && value.substr(lastAtPos + 1).match(/^[^@\s]*$/)) {
      const input = inputRef.current?.input;
      if (input) {
        const rect = input.getBoundingClientRect();
        const cursorPos = getCursorPosition(input);

        setMentionPosition({
          x: rect.left + cursorPos.left,
          y: rect.top + cursorPos.top - 200
        });
      }

      const searchText = value.substring(lastAtPos + 1).toLowerCase();
      const filteredUsers = Array.from(new Set(
        messages
          .filter(m => m.user.toLowerCase().includes(searchText))
          .map(m => ({
            username: m.user,
            deviceId: m.deviceId
          }))
      ));

      setMentionUsers(filteredUsers);
      setShowMention(filteredUsers.length > 0);
      setActiveMentionIndex(0);
    } else {
      setShowMention(false);
    }
  };

  const getCursorPosition = (input) => {
    const selection = window.getSelection();
    const range = selection.getRangeAt(0);
    const clonedRange = range.cloneRange();
    const cursorSpan = document.createElement('span');
    cursorSpan.textContent = '\u200b';
    clonedRange.insertNode(cursorSpan);
    clonedRange.setStartAfter(cursorSpan);

    const rect = cursorSpan.getBoundingClientRect();
    cursorSpan.parentNode.removeChild(cursorSpan);

    return {
      left: rect.left - input.getBoundingClientRect().left,
      top: rect.top - input.getBoundingClientRect().top
    };
  };

  const handleMentionSelect = (user) => {
    const currentValue = inputMsg;
    const lastAtPos = currentValue.lastIndexOf('@');

    setInputMsg(
      currentValue.substring(0, lastAtPos) +
      `@${user.username} ` +
      currentValue.substring(lastAtPos + user.username.length + 1)
    );
    setShowMention(false);
    inputRef.current?.focus();
  };

  const handleInputKeyDown = (e) => {
    if (showMention) {
      if (e.key === 'ArrowUp') {
        e.preventDefault();
        setActiveMentionIndex(prev =>
          prev <= 0 ? mentionUsers.length - 1 : prev - 1
        );
      } else if (e.key === 'ArrowDown') {
        e.preventDefault();
        setActiveMentionIndex(prev =>
          prev >= mentionUsers.length - 1 ? 0 : prev + 1
        );
      } else if (e.key === 'Enter' && mentionUsers.length > 0) {
        e.preventDefault();
        handleMentionSelect(mentionUsers[activeMentionIndex]);
      } else if (e.key === 'Escape') {
        setShowMention(false);
      }
    } else if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      sendMessage();
    }

    // 按ESC键关闭表情选择器
    if (e.key === 'Escape' && showEmojiPicker) {
      setShowEmojiPicker(false);
    }
  };

  // 处理表情点击事件
  const handleEmojiClick = (event) => {
    const emojiBtn = event.currentTarget;
    const rect = emojiBtn.getBoundingClientRect();

    setEmojiPosition({
      x: rect.left,
      y: rect.top + window.scrollY
    });

    setShowEmojiPicker(!showEmojiPicker);
  };

  // 处理选择表情
  const handleEmojiSelect = (emoji) => {
    setInputMsg(prev => prev + emoji);
    setShowEmojiPicker(false);
    inputRef.current?.focus();
  };
  
  // 处理拼图点击事件
  const handlePuzzleClick = () => {
    setShowImageUploader(true);
  };
  
  // 处理图片选择
  const handleImageSelect = (imageUrl) => {
    setSelectedImage(imageUrl);
    // 自动发送图片消息
    setTimeout(() => {
      sendMessage();
    }, 100);
  };

  const sendMessage = () => {
    // 如果有选中的图片，则发送图片消息
    const messageText = selectedImage || inputMsg.trim();
    if (!messageText) return;

    const msgData = {
      user: userData.username,
      deviceId: userData.deviceId,
      text: messageText,
      time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
      timestamp: Date.now(),
      mentions: extractMentions(inputMsg),
      isImage: !!selectedImage
    };

    try {
      wsRef.current.send(JSON.stringify(msgData));

      // 保存消息到messageStore，使其在Message组件中可见
      const messageWithIsMe = {
        ...msgData,
        isMe: true
      };
      saveMessage(messageWithIsMe);

      setInputMsg('');
      setSelectedImage('');
      setShowMention(false);
    } catch (err) {
      antdMessage.error('发送失败: ' + err.message);
    }
  };

  const handleSaveName = (newName) => {
    const updatedUserData = {
      ...userData,
      username: newName
    };

    setUserData(updatedUserData);
    // 更新messageStore中的用户数据
    updateUserData(updatedUserData);

    if (wsRef.current?.readyState === 1) {
      wsRef.current.send(JSON.stringify({
        type: 'user_update',
        deviceId: userData.deviceId,
        newName: newName
      }));
    }

    setMessages(prev =>
      prev.map(m =>
        m.deviceId === userData.deviceId
          ? { ...m, user: newName }
          : m
      )
    );

    antdMessage.success('昵称修改成功');
    setSettingVisible(false);
  };

  const clearChatHistory = () => {
    setMessages([]);
    localStorage.removeItem(MESSAGES_KEY);
    // 同时清除messageStore中的消息
    import('./messageStore').then(({ clearAllMessages }) => {
      clearAllMessages();
    });
    antdMessage.success('聊天记录已删除');
  };

  const calculateBubbleMetrics = (text) => {
    if (!text || typeof text !== 'string') {
      return {
        widthPercent: 60,
        padding: '8px 12px'
      };
    }

    const charWidth = Array.from(text).reduce((acc, char) =>
      acc + (/[\u4e00-\u9fa5]/.test(char) ? 2 : 1), 0);

    const widthPercent = Math.min(90, Math.max(30, 30 + charWidth * 0.4));
    const paddingHorizontal = Math.min(24, Math.max(12, 12 + charWidth * 0.2));
    const paddingVertical = Math.min(16, Math.max(8, 8 + charWidth * 0.05));

    return {
      widthPercent,
      padding: `${paddingVertical}px ${paddingHorizontal}px`
    };
  };

  const navigate = useNavigate();
  const handleMessageClick = () => {
    navigate('/message')
  }

  return (
    <div className={styles.chatContainer}>
      <div className={styles.chatHeader}>
        <span className={styles.out} onClick={handleMessageClick}>＜</span>
        <Avatar icon={<UserOutlined />} />
        <span
          style={{ marginLeft: 8, cursor: 'pointer' }}
          onClick={() => setSettingVisible(true)}
        >
          {otherUserName}
        </span>
        <Popconfirm
          title="确定要永久删除所有聊天记录吗？"
          onConfirm={clearChatHistory}
          okText="确定"
          cancelText="取消"
          placement="bottomRight"
        >
          <Button
            type="text"
            icon={<DeleteOutlined />}
            style={{ marginLeft: 'auto', color: '#ff4d4f' }}
          />
        </Popconfirm>
      </div>

      <div className={styles.messageList} ref={listRef}>
        <List
          dataSource={messages}
          renderItem={(item) => {
            if (!item || typeof item.text !== 'string') return null;

            const metrics = calculateBubbleMetrics(item.text || '');
            return (
              <div
                className={`${styles.messageBubbleContainer} ${item.isMe ? styles.me : styles.others}`}
                style={{
                  '--bubble-width': `${metrics.widthPercent}%`,
                  '--bubble-padding': metrics.padding
                }}
              >
                <div className={styles.messageBubble}>
                  <div className={styles.messageSender}>
                    <Avatar size="small">{item.user.charAt(0)}</Avatar>
                    <span className={styles.senderName}>{item.user}</span>
                    <span className={styles.messageTime}>{item.time}</span>
                  </div>
                  <div className={styles.messageText}>
                    {renderMessageText(item.text)}
                    {item.mentions?.includes(userData.username) && !item.isMe && (
                      <div style={{
                        color: '#ff4d4f',
                        fontSize: 12,
                        marginTop: 4
                      }}>
                        提到了你
                      </div>
                    )}
                  </div>
                </div>
              </div>
            );
          }}
        />
      </div>

      <div className={styles.inputArea}>
        <span
          onClick={handleEmojiClick}
          style={{ cursor: 'pointer', fontSize: '20px' }}
        >
          😊
        </span>
        <span 
          onClick={handlePuzzleClick}
          style={{ cursor: 'pointer', fontSize: '20px' }}
        >
          🧩
        </span>
        <Input.TextArea
          ref={inputRef}
          value={inputMsg}
          onChange={handleInputChange}
          onKeyDown={handleInputKeyDown}
          placeholder={selectedImage ? "图片已选择，点击发送" : "请输入消息"}
          autoSize={{ minRows: 1, maxRows: 4 }}
          style={{ width: '280px', marginLeft: '5px' }}
        />
        <Button
          type="primary"
          icon={<SendOutlined />}
          onClick={sendMessage}
          disabled={!inputMsg.trim() && !selectedImage}
          style={{ marginTop: 9, marginLeft: 10 }}
        />
      </div>

      {
        showMention && (
          <MentionPopover
            users={mentionUsers}
            onSelect={handleMentionSelect}
            position={mentionPosition}
            activeIndex={activeMentionIndex}
          />
        )
      }

      {
        showEmojiPicker && (
          <EmojiPicker
            onSelect={handleEmojiSelect}
            position={emojiPosition}
          />
        )
      }

      <UserSettingModal
        visible={settingVisible}
        initialName={userData.username}
        onSave={handleSaveName}
        onCancel={() => setSettingVisible(false)}
      />
      
      <ImageUploader 
        visible={showImageUploader}
        onCancel={() => setShowImageUploader(false)}
        onImageSelect={handleImageSelect}
      />
    </div >
  );
}

export default Chat;
